<?php

namespace Portal\Api;

use Portal\Common\DataApi as Api;
use Portal\Domain\Dept as DeptDomain;
use PhalApi\Exception\BadRequestException;

// use PhalApi\Api;

/**
 *部门接口
 * @author chenwengen 20240420
 */
class Dept extends Api
{
    public function getRules()
    {
        return array(
        'deptLists' => array(
                'keywords' => array('name' => 'keywords', 'require' => false, 'desc' => '关键字(部门名称)'),
                'status' =>  array('name' => 'status', 'type' => 'enum', 'require' => false,'range' => array('0', '1'),'desc' => '状态'),
            ),
            'createData' => array(
                'parent_id' => array('name' => 'parentId', 'type' => 'int',  'require' => true, 'min' => 0, 'desc' => '父id'),
                'name' => array('name' => 'name', 'require' => true, 'desc' => '部门名称'),
                'code' => array('name' => 'name', 'require' => true, 'desc' => '部门编号'),
                'status' => array('name' => 'status', 'type' => 'enum', 'require' => false,'range' => array('0', '1'),'desc' => '状态(1:启用;0:禁用)'),
                'sort' => array('name' => 'sort', 'type' => 'int', 'require' => false,'min' => 0,'desc' => '排序(数字越小排名越靠前)'),
              ),
            'deleteData' => array(
                'ids' => array('name' => 'id', 'require' => true, 'type' => 'int', 'min' => 1, 'desc' => \PhalApi\T('ID to delete')),
            ),
            'deleteDataIDs' => array(
                'ids' => array('name' => 'ids', 'type' => 'array', 'format' => 'explode', 'seperator' => ',', 'require' => true, 'desc' => \PhalApi\T('ids to delete'))
            ),
            'getData' => array(
                'id' => array('name' => 'id', 'type' => 'int', 'require' => true, 'min' => 1, 'desc' => 'ID'),
            ),
            'updateData' => array(
                'id' => array('name' => 'id', 'type' => 'int', 'require' => true, 'min' => 1, 'desc' => 'ID'),
                'parent_id' => array('name' => 'parentId', 'type' => 'int',  'require' => true, 'min' => 0, 'desc' => '父id'),
                'name' => array('name' => 'name', 'require' => true, 'desc' => '部门名称'),
                'status' => array('name' => 'status', 'type' => 'enum', 'require' => false,'range' => array('0', '1'),'desc' => '状态(1:启用;0:禁用)'),
                'sort' => array('name' => 'sort', 'type' => 'int', 'require' => false,'min' => 0,'desc' => '排序(数字越小排名越靠前)'),
                'code' => array('name' => 'name', 'require' => true, 'desc' => '部门编号'),
            ),
        );
    }
    protected function getDataModel()
    {
        return  new \Portal\Model\Dept();
    }
    /**
     * 当在方法使用ingore注解时，则不会显示在接口列表文档上
     * 用于查询接口传入部门id 回调部门id是否存在
     * @ignore
     */
    public static function deptList($value, $rule)
    {
        $value = intval($value);
        $depData = \Portal\Model\Dept::notorm()->select('id')->where(['id' => $value,'status' => 1,'is_deleted' => 0])->fetchOne();
        if (is_array($depData) && !empty($depData)) {
            return $value;
        }

        throw new BadRequestException('部门id不存在');
    }
    /**
       * 获取部门下拉选项
       * @desc 获取部门下拉选项
       */
    public function options()
    {
        $this->permissionRequired(["sys:dept:query"]);
        $hasPermissionData = $this->dataPermissionRequired("select");
        $deptDomain = new DeptDomain();
        $returnData = $deptDomain->getDeptLevel($hasPermissionData);
        return $returnData;
    }
    /**
       * 获取部门列表
       * @desc 获取部门下拉选项
       */
    public function deptLists()
    {
        $this->permissionRequired(["sys:dept:query"]);
        $where = [];
        if ($this->keywords !== null && trim($this->keywords) != '') {
            $where['name LIKE ?'] = array("%$this->keywords%");
        }
        if ($this->status !== null) {
            $where['status'] = $this->status;
        }
        $deptDomain = new DeptDomain();
        $returnData = $deptDomain->getDeptList($where);
        return $returnData;
    }
    /**
    * 新增部门
    * @desc 新增部门
    * @return int id 新纪录的ID
    */
    public function createData()
    {
        $this->permissionRequired(["sys:dept:add"]);

        $model = $this->getDataModel();

        $array_keys = array_keys($this->getApiRules());
        $newData = [];
        foreach ($array_keys as $key) {
            if ($this->$key !== null) {
                $newData[$key] = $this->$key;
            }
        }
        // 检测必传字段
        foreach ($this->createDataRequireKeys() as $key) {
            if (!isset($newData[$key]) || $newData[$key] === '') {
                throw new BadRequestException(\PhalApi\T('{name} require, but miss', array('name' => $key)));
            }
        }
        // 排除字段
        foreach ($this->createDataExcludeKeys() as $key) {
            unset($newData[$key]);
        }

        // 更多初始化的字段数据
        $newData = $this->beforeCreateData($newData);

        if (empty($newData)) {
            throw new BadRequestException(\PhalApi\T('miss post data'));
        }

        $id = 0;
        try {
            $id = $model->insert($newData);
        } catch (\PDOException $ex) {
            throw new BadRequestException(\PhalApi\DI()->debug ? $ex->getMessage() : \PhalApi\T('system error, please contact engeneer'));
        }

        return $this->returnDataResult(array('id' => intval($id)));
    }

    // 必须提供的字段
    protected function createDataRequireKeys()
    {
        return array('parent_id','name');
    }

    // 不允许客户端写入的字段
    protected function createDataExcludeKeys()
    {
        return array('create_time','update_time','is_deleted','create_by','update_by','tree_path');
    }

    // 创建时更多初始化的数据
    protected function beforeCreateData($newData)
    {
        $time = time();
        $newData['create_time'] = $time;
        $newData['update_time'] = $time;
        $newData['create_by'] = \PhalApi\DI()->admin->getId();
        if ($newData['parent_id'] == 0) {
            $newData['tree_path'] = '0';
        } else {
            //获取树等级
            $deptDomain = new DeptDomain();
            $treePath = $deptDomain->getTreePath($newData['parent_id']);
            $newData['tree_path'] = implode(',', $treePath);
        }

        return $newData;
    }

    /**
     * 根据ID删除数据
     * @desc 根据单个ID删除数据，也可以调整成根据自定义的条件删除数据
     */
    // public function deleteData()
    // {
    //     $where = array('id' => $this->id);

    //     $model = $this->getDataModel();
    //     $rows = !empty($where) ? $model->deleteAll($where) : 0;

    //     return $this->returnDataResult(array('deleted_num' => $rows));
    // }

    // 删除数据的条件加工
    protected function getDeleteDataWhere($where)
    {
        return $where;
    }

    /**
     * 批量删除
     * @desc 通用数据接口，根据ID批量删除数据
     */
    public function deleteDataIDs()
    {
        $this->permissionRequired(["sys:dept:delete"]);
        $model = $this->getDataModel();
        if (!$this->ids) {
            throw new BadRequestException("请指定要删除的部门ID", 4);

        }
        $toDeleteIdDatas = $this->getDataModel()::notorm()->select('id,name,create_by')->where(['id' => $this->ids,'is_deleted' => 0])->fetchAll();
        if (!$toDeleteIdDatas) {
            throw new BadRequestException("没有要删除的数据", 4);
        }
        $toDeleteIds = [];
        foreach ($toDeleteIdDatas as $toDeleteIdData) {
            $toDeleteIds[] = $toDeleteIdData['id'];
        }
        # 检查是否存在子部门
        $childDeptDatas = $this->getDataModel()::notorm()->select('id')->where(['parent_id' => $toDeleteIds,'is_deleted' => 0])->fetchAll();
        if ($childDeptDatas) {
            throw new BadRequestException("存在子部门，无法删除", 3);
        }
        # 检查每个部门的权限
        $unauthorizedDepts = [];
        foreach ($toDeleteIdDatas as $toDeleteIdData) {
            $hasPermission = $this->dataPermissionRequired("delete", $toDeleteIdData['create_by']);
            if (!$hasPermission) {
                $unauthorizedDepts[] = $toDeleteIdData['name'];
            }
        }
        if (!empty($unauthorizedDepts)) {
            throw new BadRequestException("无权限删除部门".implode(',', $unauthorizedDepts), 3);
        }
        $rows = $model->updateAll(['id' => $toDeleteIds], ['is_deleted' => 1]) ?: 0;

        return $this->returnDataResult(array('deleted_num' => $rows));
    }

    /**
     * 获取一条数据
     * @desc 通用数据接口，根据ID获取一条数据
     * @return object
     * @exception 403 部门信息不存在
     */
    public function getData()
    {
        $this->permissionRequired(["sys:dept:query"]);
        $where = array('id' => $this->id);
        $whereParams = array();
        $select = $this->getDataSelect();
        $where['is_deleted'] = 0;
        // 前置条件加工
        $where = $this->getGetDataWhere($where);

        $model = $this->getDataModel();
        $data = $model->getData($where, $whereParams, $select);
        if (!$data) {
            throw new BadRequestException("总门信息不存在", 3);
        }
        $data = $this->afterGetData($data);
        $hasPermission = $this->dataPermissionRequired("select", $data['create_by']);
        if (!$hasPermission) {
            throw new BadRequestException("无权限查看此部门", 3);
        }
        return $this->returnDataResult($data);
    }

    // 获取单个数据时需要返回的字段
    protected function getDataSelect()
    {
        return 'id,name,parent_id AS parentId,status,sort,create_by,code';
    }

    // 前置条件加工
    protected function getGetDataWhere($where)
    {
        return $where;
    }

    // 取到数据后的加工处理
    protected function afterGetData($data)
    {
        return $data;
    }

    /**
     * 修改部门
     * @desc 修改部门
     * @return int|boolean updated_num 更新的数据条数，0表示无更新，1表示更新成功
     */
    public function updateData()
    {
        $this->permissionRequired(["sys:dept:edit"]);
        $model = $this->getDataModel();
        // $updateData = $this->data;
        $array_keys = array_keys($this->getApiRules());
        $updateData = [];
        foreach ($array_keys as $key) {
            if ($this->$key !== null && $key !== 'data') {
                $updateData[$key] = $this->$key;
            }
        }
        unset($updateData['id']);

        foreach ($this->updateDataRequireKeys() as $key) {
            if (!isset($updateData[$key]) || $updateData[$key] === '') {
                throw new BadRequestException(\PhalApi\T('{name} require, but miss', array('name' => $key)));
            }
        }

        foreach ($this->updateDataExcludeKeys() as $key) {
            unset($updateData[$key]);
        }

        if (empty($updateData)) {
            throw new BadRequestException(\PhalApi\T('miss update data'));
        }
        $data = $this->getDataModel()::notorm()->select('id,create_by')->where(['id' => $this->id,'is_deleted' => 0])->fetchOne();
        if (!$data) {
            throw new BadRequestException("部门不存在或已被删除", 3);
        }
        $hasPermission = $this->dataPermissionRequired("update", $data['create_by']);
        if (!$hasPermission) {
            throw new BadRequestException("无权限修改此部门", 3);
        }
        $updateData = $this->beforeUpdateData($updateData);

        try {
            $where = array('id' => $this->id);
            $where = $this->getUpdateDataWhere($where);

            $rows = $model->updateAll($where, $updateData);
            return $this->returnDataResult(array('updated_num' => $rows));
        } catch (\PDOException $ex) {
            throw new BadRequestException(\PhalApi\DI()->debug ? $ex->getMessage() : \PhalApi\T('system error, please contact engeneer'));
        }
    }

    // 更新时必须提供的字段
    protected function updateDataRequireKeys()
    {
        return array('parent_id');
    }

    // 更新时不允许更新的字段
    protected function updateDataExcludeKeys()
    {
        return array('create_time','update_time','is_deleted','create_by','update_by','tree_path');
    }

    // 获取更新数据的条件
    protected function getUpdateDataWhere($where)
    {
        return $where;
    }

    // 在更新数据前的处理
    protected function beforeUpdateData($updateData)
    {
        $time = time();
        $updateData['update_time'] = $time;
        $updateData['update_by'] = \PhalApi\DI()->admin->getId();
        //判断是否有修改过顶级id
        $getParentData = \Portal\Model\Dept::notorm()->select('parent_id')->where(['id' => $this->id])->fetchOne();
        if (isset($getParentData['parent_id']) && intval($getParentData['parent_id']) != $updateData['parent_id']) {
            //有修改过父级菜单，重新获取等级树
            if ($updateData['parent_id'] == 0) {
                $updateData['tree_path'] = '0';
            } else {
                //获取树等级
                $deptDomain = new DeptDomain();
                $treePath = $deptDomain->getTreePath($updateData['parent_id']);
                $updateData['tree_path'] = implode(',', $treePath);
            }
        }
        return $updateData;
    }
}
